﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.Text;
using System.Web;
using NetBay.Core.BusinessEntities;
using Rio.Doc.Business.Repository;
using System.Configuration;
using Rio.Applications.Web.Services.BusinessEntities;
using System.ServiceModel;

#endregion

namespace Rio.Applications.Web.Services
{
    #region Enums
    /// <summary>
    /// List of name settings
    /// </summary>
    public enum ParameterSession
    {
        /// <summary>
        /// User in session
        /// </summary>
        [DescriptionAttribute("CurrentUser")]
        CurrentUser = 0,
        /// <summary>
        /// Spécify the NTLM Account
        /// </summary>
        [DescriptionAttribute("NTLMAccount")]
        NTLMAccount,
        /// <summary>
        /// Culture in session
        /// </summary>
        [DescriptionAttribute("Culture")]
        Culture,
        /// <summary>
        /// License Key
        /// </summary>
        [DescriptionAttribute("License Key")]
        LicenseKey,
    }
    #endregion

    /// <summary>
    /// Class to handle Business entities in a RIA services
    /// </summary>
    [ServiceBehavior(MaxItemsInObjectGraph = 2147483647)]
    [EnableClientAccess(RequiresSecureEndpoint = false)]
    public partial class BusinessEntitiesDomainService : DomainService
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_lOrganisationId"></param>
        /// <param name="p_lFolderTypeId"></param>
        /// <param name="p_oFoldertypeRepository"></param>
        /// <returns></returns>
        private User GetFolderTypeRepository(long p_lOrganisationId, long p_lFolderTypeId, out FolderTypeRepository p_oFoldertypeRepository)
        {
            p_oFoldertypeRepository = null;
            OrganizationRepository l_oOrganisation = null;

            var l_oUserInSession = GetOrganisationRepository(p_lOrganisationId, out l_oOrganisation);

            // We must search the correct FolderType
            p_oFoldertypeRepository = (FolderTypeRepository)l_oOrganisation.FolderTypesList.Find(item => item.Identifier == p_lFolderTypeId);
            // Check if the FolderType is founded
            if (p_oFoldertypeRepository == null)
            {
                throw new Exception("FolderType(" + p_lFolderTypeId + ") in Organisation(" + p_lOrganisationId + ") not found");
            }

            return l_oUserInSession;
        }

        private User GetOrganisationRepository(long p_lOrganisationId, out OrganizationRepository p_oOrganisationRepository)
        {
            p_oOrganisationRepository = null;

            // First, find the FolderType from session
            var l_oUserInSession = GetUser();

            // So, we must find the Organisation from all groups that this user is owned
            foreach (GroupRepository l_oGroup in l_oUserInSession.GroupList)
            {
                // We must search the correct organisation
                p_oOrganisationRepository = (OrganizationRepository)l_oGroup.OrganizationList.Find(item => item.Identifier == p_lOrganisationId);
                if (p_oOrganisationRepository != null)
                    break;
            }
            // Check if the Organisation is founded
            if (p_oOrganisationRepository == null)
            {
                throw new Exception("Organisation(" + p_lOrganisationId + ") not found");
            }

            return l_oUserInSession;
        }

        /// <summary>
        /// Gets the user.
        /// </summary>
        /// <returns></returns>
        private User GetUser()
        {
            if (HttpContext.Current.Session[ParameterSession.CurrentUser.szGetDescription()] == null)
                throw new Exception("Unable to find a User!");

            return (User)HttpContext.Current.Session[ParameterSession.CurrentUser.szGetDescription()];
        }

        /// <summary>
        /// Creates the rioscan file user.
        /// </summary>
        /// <param name="p_lUserId">The P_L user id.</param>
        /// <param name="p_szLastName">Last name of the P_SZ.</param>
        /// <param name="p_szFirstName">First name of the P_SZ.</param>
        /// <param name="p_szPath">The P_SZ path.</param>
        /// <param name="SessionId">The session id.</param>
        private void CreateRioscanFileUser(long p_lUserId, string p_szLastName, string p_szFirstName, string p_szPath, string SessionId)
        {
            //var L_sRefreshScanGuid = Guid.NewGuid().ToString("N");
            HttpContext.Current.Session["RefreshScanGuid"] = SessionId;
            var L_sEndPointAddress = ConfigurationManager.AppSettings["RioWCFServices_EndPoint"];

            var l_sParameter = String.Format(@"<Parameters><UserID>{0}</UserID><LastName>{1}</LastName><FirstName>{2}</FirstName><WindowSmallMode>false</WindowSmallMode><RefreshScanGuid>{3}</RefreshScanGuid><EndPointAdress>{4}</EndPointAdress></Parameters>", p_lUserId, p_szLastName, p_szFirstName, SessionId, L_sEndPointAddress);
            var l_sParameter2 = String.Format(@"<Parameters><UserID>{0}</UserID><LastName>{1}</LastName><FirstName>{2}</FirstName><WindowSmallMode>true</WindowSmallMode><RefreshScanGuid>{3}</RefreshScanGuid><EndPointAdress>{4}</EndPointAdress></Parameters>", p_lUserId, p_szLastName, p_szFirstName, SessionId, L_sEndPointAddress);
            if (Directory.Exists(p_szPath) == false)
            {
                Directory.CreateDirectory(p_szPath);
            }
            File.WriteAllText(GetFullPathFile(SessionId, p_szPath), l_sParameter, Encoding.UTF8);
            File.WriteAllText(GetFullPathAdminFile(SessionId, p_szPath), l_sParameter2, Encoding.UTF8);
        }

        /// <summary>
        /// Removes the rioscan file user.
        /// </summary>
        /// <param name="SessionId">The session id.</param>
        /// <param name="p_szPath">The P_SZ path.</param>
        private void RemoveRioscanFileUser(string SessionId, string p_szPath)
        {
            File.Delete(GetFullPathFile(SessionId, p_szPath));
            File.Delete(GetFullPathAdminFile(SessionId, p_szPath));
        }

        /// <summary>
        /// Gets the full path file.
        /// </summary>
        /// <param name="SessionId">The session id.</param>
        /// <param name="p_szPath">The P_SZ path.</param>
        /// <returns></returns>
        private string GetFullPathFile(string SessionId, string p_szPath)
        {
            return Path.Combine(p_szPath, SessionId) + ".rioscan";
        }

        /// <summary>
        /// Gets the full path admin file.
        /// </summary>
        /// <param name="SessionId">The session id.</param>
        /// <param name="p_szPath">The P_SZ path.</param>
        /// <returns></returns>
        private string GetFullPathAdminFile(string SessionId, string p_szPath)
        {
            return Path.Combine(p_szPath, SessionId) + "_admin.rioscan";
        }

        private Dictionary<T, V> CheckDictionaryValues<T, V>(Dictionary<T, V> p_oDicValorization)
        {
            var l_oNewDic = new Dictionary<T, V>();
            var l_oValorization = p_oDicValorization.Where(l_oItem => l_oItem.Value != null);
            foreach (KeyValuePair<T, V> l_oKvp in l_oValorization)
            {
                l_oNewDic.Add(l_oKvp.Key, l_oKvp.Value);
            }

            return l_oNewDic;
        }

        private Dictionary<Index, T> RebuildDictionaryIndex<T>(Dictionary<long, T> p_oDicSource, List<Index> p_oListIndex)
        {
           var l_oDicRebuilded = new Dictionary<Index, T>();

            foreach (KeyValuePair<long, T> l_oKvp in CheckDictionaryValues<long, T>(p_oDicSource))
            {
                var l_oIndex = p_oListIndex.Find(item => item.Indentifier == l_oKvp.Key);
                if (l_oIndex == default(Index))
                {
                    throw new Exception("Unable to find Index(" + l_oKvp.Key + ")");
                }
                l_oDicRebuilded.Add(l_oIndex, l_oKvp.Value);
            }

            return l_oDicRebuilded;
        }

    }
}
